home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / indents.zip / args.c next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  14.3 KB  |  542 lines

  1. /**
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted provided
  8.  * that the above copyright notice and this paragraph are duplicated in all
  9.  * such forms and that any documentation, advertising materials, and other
  10.  * materials related to such distribution and use acknowledge that the
  11.  * software was developed by the University of California, Berkeley, the
  12.  * University of Illinois, Urbana, and Sun Microsystems, Inc.  The name of
  13.  * either University or Sun Microsystems may not be used to endorse or
  14.  * promote products derived from this software without specific prior written
  15.  * permission. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
  17.  * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #include "globals.h"
  21.  
  22. #ifndef lint
  23. # ifndef ANSIC
  24. static char     sccsid[] = "@(#)args.c    6.0 (Berkeley) 92/06/15";
  25. # endif         /* ANSIC */
  26. #endif          /* not lint */
  27.  
  28. /* Argument scanning and profile reading code.  Default parameters are set
  29.  * here as well. */
  30.  
  31. #include <ctype.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34.  
  35. #ifdef ANSIC
  36. static void     scan_profile(FILE *);
  37. #endif          /* ANSIC */
  38.  
  39. /* Profile types */
  40. #define PRO_SPECIAL     1       /* special case */
  41. #define PRO_BOOL        2       /* Boolean */
  42. #define PRO_INT         3       /* integer */
  43. #define PRO_FONT        4       /* troff font */
  44.  
  45. /* Profile specials for Booleans. Booleans can be set to USE or IGNORE. USE
  46.  * reads the value, IGNORE ignores the value and keeps the default */
  47. #define USE             0       /* turn it off */
  48.  
  49. /* Profile specials for specials */
  50. #define IGNORE          1       /* ignore it */
  51. #define KEY             4       /* type (keyword) */
  52.  
  53. char           *option_source = "?";
  54.  
  55. /* N.B.: option names can't start with n */
  56. struct pro {
  57.     char           *p_name;     /* name, e.g. -br, -cli */
  58.     int             p_type;     /* type (int, bool, special) */
  59.     int             p_default;  /* the default value (if int) */
  60.     int             p_special;  /* depends on type */
  61.     int            *p_obj;      /* the associated variable */
  62. }               pro[] = {
  63.     {
  64.         "+", PRO_BOOL, true, USE, &cplus
  65.     },
  66.     {
  67.         "T", PRO_SPECIAL, 0, KEY, 0
  68.     },
  69.     {
  70.         "bacc", PRO_BOOL, false, USE, &blanklines_around_conditional_compilation
  71.     },
  72.     {
  73.         "bad", PRO_BOOL, false, USE, &blanklines_after_declarations
  74.     },
  75.     {
  76.         "badp", PRO_BOOL, false, USE, &blanklines_after_declarations_at_proctop
  77.     },
  78.     {
  79.         "bap", PRO_BOOL, false, USE, &blanklines_after_procs
  80.     },
  81.     {
  82.         "bbb", PRO_BOOL, false, USE, &blanklines_before_blockcomments
  83.     },
  84.     {
  85.         "bc", PRO_BOOL, false, USE, &ps.leave_comma
  86.     },
  87.     {
  88.         "br", PRO_BOOL, true, USE, &btype_2
  89.     },
  90.     {
  91.         "brr", PRO_BOOL, false, USE, &btype_3
  92.     },
  93.     {
  94.         "bs", PRO_BOOL, false, USE, &Bill_Shannon
  95.     },
  96.     {
  97.         "c", PRO_INT, 33, 0, &ps.com_ind
  98.     },
  99.     {
  100.         "cci", PRO_INT, 4, 0, &ps.case_code_indent
  101.     },
  102.     {
  103.         "cd", PRO_INT, 0, 0, &ps.decl_com_ind
  104.     },
  105.     {
  106.         "cdb", PRO_BOOL, false, USE, &comment_delimiter_on_blankline
  107.     },
  108.     {
  109.         "ce", PRO_BOOL, true, USE, &cuddle_else
  110.     },
  111.     {
  112.         "ci", PRO_INT, 0, 0, &continuation_indent
  113.     },
  114.     {
  115.         "cli", PRO_INT, 0, 0, &ps.case_indent
  116.     },
  117.     {
  118.         "cp", PRO_INT, 17, 0, &ps.else_endif_col
  119.     },
  120.     {
  121.         "d", PRO_INT, 0, 0, &ps.unindent_displace
  122.     },
  123.     {
  124.         "di", PRO_INT, 16, 0, &ps.decl_indent
  125.     },
  126.     {
  127.         "dj", PRO_BOOL, false, USE, &ps.ljust_decl
  128.     },
  129.     {
  130.         "eei", PRO_BOOL, false, USE, &extra_expression_indent
  131.     },
  132.     {
  133.         "ei", PRO_BOOL, true, USE, &ps.else_if
  134.     },
  135.     {
  136.         "fb", PRO_FONT, 0, 0, (int *) &bodyf
  137.     },
  138.     {
  139.         "fbc", PRO_FONT, 0, 0, (int *) &blkcomf
  140.     },
  141.     {
  142.         "fbx", PRO_FONT, 0, 0, (int *) &boxcomf
  143.     },
  144.     {
  145.         "fc", PRO_FONT, 0, 0, (int *) &scomf
  146.     },
  147.     {
  148.         "fc1", PRO_BOOL, false, USE, &format_col1_comments
  149.     },
  150.     {
  151.         "fk", PRO_FONT, 0, 0, (int *) &keywordf
  152.     },
  153.     {
  154.         "fs", PRO_FONT, 0, 0, (int *) &stringf
  155.     },
  156.     {
  157.         "i", PRO_INT, 4, 0, &ps.ind_size
  158.     },
  159.     {
  160.         "ip", PRO_BOOL, true, USE, &ps.indent_parameters
  161.     },
  162.     {
  163.         "l", PRO_INT, 78, 0, &max_col
  164.     },
  165.     {
  166.         "lc", PRO_INT, 0, 0, &block_comment_max_col
  167.     },
  168.     {
  169.         "ldefs", PRO_BOOL, false, USE, &list_defines
  170.     },
  171.     {
  172.         "lp", PRO_BOOL, true, USE, &lineup_to_parens
  173.     },
  174.     {
  175.         "pcs", PRO_BOOL, false, USE, &proc_calls_space
  176.     },
  177.     {
  178.         "pro", PRO_BOOL, true, USE, &useProfile
  179.     },
  180.     {
  181.         "prs", PRO_BOOL, false, USE, &parens_space
  182.     },
  183.     {
  184.         "ps", PRO_BOOL, false, USE, &pointer_as_binop
  185.     },
  186.     {
  187.         "psl", PRO_BOOL, false, USE, &procnames_start_line
  188.     },
  189.     {
  190.         "sc", PRO_BOOL, true, USE, &star_comment_cont
  191.     },
  192.     {
  193.         "sob", PRO_BOOL, false, USE, &swallow_optional_blanklines
  194.     },
  195.     {
  196.         "st", PRO_BOOL, false, USE, &useStdio
  197.     },
  198.     {
  199.         "tabs", PRO_INT, 8, 0, &tabsize
  200.     },
  201.     {
  202.         "tabu", PRO_BOOL, false, 0, &usetabs
  203.     },
  204.     {
  205.         "troff", PRO_BOOL, false, USE, &troff
  206.     },
  207.     {
  208.         "v", PRO_BOOL, false, USE, &verbose
  209.     },
  210.     {
  211.         0, 0, 0, 0, 0
  212.     },
  213.     /* whew! */
  214. };
  215.  
  216. /**
  217.  * NAME: void set_profile(void)
  218.  *
  219.  * FUNCTION: set_profile reads $HOME/indent.pro and ./indent.pro and handles
  220.  * arguments given in these files.
  221.  *
  222.  * ALGORITHM:
  223.  *
  224.  * PARAMETERS: Reads the environment.
  225.  *
  226.  * RETURNS:
  227.  *
  228.  * GLOBALS READ:
  229.  *
  230.  * GLOBALS CHANGED:
  231.  *
  232.  * CALLED BY:
  233.  *
  234.  * HISTORY: Peter Hadfield 09-03-93 Removed the '.' (UNIX hidden file marker)
  235.  * from indent.pro to allow the same code to be used for DOS and UNIX.
  236.  *
  237.  * Added display of profile file path for verbose option.
  238.  * Fixed problem with (null) being written into fname if getenv() returns NULL.
  239.  *
  240.  * Added reading of a profile file with the same path and name as the binary
  241.  * (but with a .pro extension).*/
  242.  
  243. #ifdef ANSIC
  244. void            set_profile(char *bin_name)
  245. #else           /* ANSIC */
  246. set_profile(bin_name)
  247.     char           *bin_name;
  248. #endif          /* ANSIC */
  249. {
  250.     FILE           *stream;
  251.     char            fname[BUFSIZ] = "";
  252.     char           *env_ptr = NULL;
  253.     static char     prof[] = "indent.pro";  /* this is no longer a UNIX
  254.                                              * hidden file so the DOS port
  255.                                              * can use the same code */
  256.     strcpy(fname, bin_name);
  257.     if (fname[strlen(fname) - 4] == '.')    /* assume its a DOS file name */
  258.         (fname[strlen(fname) - 4] = '\0');  /* remove the extension */
  259.     strcat(fname, ".pro");
  260.     if ((stream = fopen(option_source = fname, "r")) != NULL) {
  261.         if ((verbose) || (show_options))
  262.             fprintf(stderr, "Reading profile file: %s", fname);
  263.         scan_profile(stream);
  264.         (void) fclose(stream);
  265.     }
  266.     env_ptr = getenv("HOME");
  267.     if (env_ptr != NULL) {
  268.         sprintf(fname, "%s/%s", env_ptr, prof);
  269.         if ((stream = fopen(option_source = fname, "r")) != NULL) {
  270.             if ((verbose) || (show_options))
  271.                 fprintf(stderr, "\nReading profile file: %s", fname);
  272.             scan_profile(stream);
  273.             (void) fclose(stream);
  274.         }
  275.     }
  276.     sprintf(fname, "%s", prof);
  277.     if ((stream = fopen(option_source = fname, "r")) != NULL) {
  278.         if ((verbose) || (show_options))
  279.             fprintf(stderr, "Reading profile file: %s", fname);
  280.         scan_profile(stream);
  281.         (void) fclose(stream);
  282.     }
  283.     option_source = "Command line";
  284. }
  285.  
  286. /** NAME:
  287.  *
  288.  * FUNCTION:
  289.  *
  290.  * ALGORITHM:
  291.  *
  292.  * PARAMETERS:
  293.  *
  294.  * RETURNS:
  295.  *
  296.  * GLOBALS READ:
  297.  *
  298.  * GLOBALS CHANGED:
  299.  *
  300.  * CALLED BY:
  301.  *
  302.  * HISTORY:
  303.  */
  304. #ifdef ANSIC
  305. static void     scan_profile(FILE * f)
  306. #else           /* ANSIC */
  307. scan_profile(f)
  308.     FILE           *f;
  309. #endif          /* ANSIC */
  310. {
  311.     int             i;
  312.     char           *p = NULL;
  313.     char            buf[BUFSIZ] = "";
  314.  
  315.     while (1) {
  316.         for (p = buf; (i = getc(f)) != EOF && (*p = (char) i) > ' '; ++p);
  317.         if (p != buf) {
  318.             *p++ = 0;
  319.             if ((verbose) || (show_options))
  320.                 fprintf(stderr, " %s", buf);
  321.             set_option(buf);
  322.         } else if (i == EOF) {
  323.             if ((verbose) || (show_options))
  324.                 fprintf(stderr, "\n\n", buf);
  325.             return;
  326.         }
  327.     }
  328. }
  329.  
  330. /** NAME:
  331.  *
  332.  * FUNCTION: Set the defaults.
  333.  *
  334.  * ALGORITHM:
  335.  *
  336.  * PARAMETERS:
  337.  *
  338.  * RETURNS:
  339.  *
  340.  * GLOBALS READ:
  341.  *
  342.  * GLOBALS CHANGED:
  343.  *
  344.  * CALLED BY:
  345.  *
  346.  * HISTORY:
  347.  *
  348.  */
  349. #ifdef ANSIC
  350. void            set_defaults(void)
  351. #else           /* ANSIC */
  352. set_defaults()
  353. #endif          /* ANSIC */
  354. {
  355.     struct pro     *p;
  356.  
  357.     for (p = pro; p->p_name; p++) {
  358.         if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT) {
  359.             *p->p_obj = p->p_default;
  360.         }
  361.     }
  362. }
  363.  
  364. /** NAME: list_options()
  365.  *
  366.  * FUNCTION: List the current options.
  367.  *
  368.  * ALGORITHM:
  369.  *
  370.  * PARAMETERS:
  371.  *
  372.  * RETURNS:
  373.  *
  374.  * GLOBALS READ:
  375.  *
  376.  * GLOBALS CHANGED:
  377.  *
  378.  * CALLED BY:
  379.  *
  380.  * HISTORY: */
  381. #ifdef ANSIC
  382. void            list_options(char *in_name)
  383. #else           /* ANSIC */
  384. list_options(in_name)
  385.     char           *in_name;
  386. #endif          /* ANSIC */
  387. {
  388.     struct pro     *p;
  389.  
  390.     fprintf(stderr, "indent: %-12s", in_name);
  391.  
  392.     for (p = pro; p->p_name; p++) {
  393.         if ((p->p_type == PRO_BOOL) && (*p->p_obj == 1)) {
  394.             fprintf(stderr, " -%s", p->p_name);
  395.         }
  396.     }
  397.     for (p = pro; p->p_name; p++) {
  398.         if (p->p_type == PRO_INT) {
  399.             fprintf(stderr, " -%s:%d", p->p_name, *p->p_obj);
  400.         }
  401.     }
  402. #if 0
  403.     fprintf(stderr, " fb  %s,%c,%d", *bodyf->font, bodyf->allcaps, bodyf->size);
  404.     fprintf(stderr, " fc  %s,%c,%d", &scomf->font, scomf->allcaps, scomf->size);
  405.     fprintf(stderr, " fbc %s,%c,%d", &blkcomf->font, blkcomf->allcaps, blkcomf->size);
  406.     fprintf(stderr, " fbx %s,%c,%d", &boxcomf->font, boxcomf->allcaps, boxcomf->size);
  407.     fprintf(stderr, " fs  %s,%c,%d", &stringf->font, stringf->allcaps, stringf->size);
  408.     fprintf(stderr, " fk  %s,%c,%d", &keywordf->font, keywordf->allcaps, keywordf->size);
  409. #endif 0
  410.     fprintf(stderr, "\n");
  411. }
  412.  
  413.  
  414. /** NAME:
  415.  *
  416.  * FUNCTION:
  417.  *
  418.  * ALGORITHM:
  419.  *
  420.  * PARAMETERS:
  421.  *
  422.  * RETURNS:
  423.  *
  424.  * GLOBALS READ:
  425.  *
  426.  * GLOBALS CHANGED:
  427.  *
  428.  * CALLED BY:
  429.  *
  430.  * HISTORY: (PETER) Added a proper string compare for finding options.
  431.  *
  432.  * Options can now be in any order in the struct.
  433.  *
  434.  * Arguments to options must be separated by a ':', e.g. -l:78
  435.  *
  436.  * If an option name starts with an 'n', assume this is a negated (off) option.
  437.  * This implies that option names can't start with an 'n' */
  438. #ifdef ANSIC
  439. void            set_option(register char *arg)
  440. #else           /* ANSIC */
  441. set_option(arg)
  442.     register char  *arg;
  443. #endif          /* ANSIC */
  444. {
  445.     struct pro     *p;
  446.     int             booleanState;
  447.     int             argptr;
  448.     int             nameptr;
  449.     char            argname[10] = "";   /* maximum length of an option name */
  450.     char            optname[10] = "";   /* maximum length of an option
  451.                                          * argument */
  452.  
  453.     /* skip the leading "-" */
  454.     argptr = 1;
  455.  
  456.     /* if the option name starts with an 'n' record it and skip it. */
  457.     if (arg[argptr] == 'n') {
  458.         argptr++;
  459.         booleanState = 0;
  460.     } else {
  461.         booleanState = 1;
  462.     }
  463.  
  464.     /* record the option name */
  465.     nameptr = 0;
  466.     while ((arg[argptr] != 0) && (arg[argptr] != ':')) {
  467.         argname[nameptr] = arg[argptr];
  468.         nameptr++;
  469.         argptr++;
  470.     }
  471.     argname[nameptr] = 0;
  472.  
  473.     /* record the option argument, if any */
  474.     nameptr = 0;
  475.     if (arg[argptr] == ':') {
  476.         argptr++;               /* skip the colon */
  477.         while (arg[argptr] != 0) {
  478.             optname[nameptr] = arg[argptr];
  479.             nameptr++;
  480.             argptr++;
  481.         }
  482.     }
  483.     optname[nameptr] = 0;
  484.  
  485.     for (p = pro; p->p_name; p++) {
  486.         if (strcmp(p->p_name, argname) == 0) {
  487.  
  488.             switch (p->p_type) {
  489.  
  490.             case PRO_BOOL:
  491.                 if (p->p_special != IGNORE)
  492.                     *p->p_obj = booleanState;
  493.                 return;
  494.  
  495.             case PRO_INT:
  496.                 if (!isdigit(*optname)) {
  497.                     fprintf(stderr, "indent: %s option: \"%s\" requires a parameter\n",
  498.                             option_source, argname);
  499.                     exit(1);
  500.                 }
  501.                 *p->p_obj = atoi(optname);
  502.                 return;
  503.  
  504.             case PRO_FONT:
  505.                 parsefont((struct fstate *) p->p_obj, optname);
  506.                 return;
  507.  
  508.             case PRO_SPECIAL:
  509.                 switch (p->p_special) {
  510.  
  511.                 case IGNORE:
  512.                     return;
  513.  
  514.                 case KEY:
  515.                     if (*optname == 0) {
  516.                         fprintf(stderr, "indent: %s option: \"%s\" requires a parameter\n",
  517.                                 option_source, argname);
  518.                         exit(1);
  519.                     } else {
  520.                         char           *str = (char *) malloc(strlen(optname) + 1);
  521.  
  522.                         strcpy(str, optname);
  523.                         addkey(str, 4);
  524.                         return;
  525.                     }
  526.                 default:
  527.                     fprintf(stderr, "indent: set_option: internal error: p_special %d\n", p->p_special);
  528.                     exit(1);
  529.                 }
  530.                 return;
  531.  
  532.             default:
  533.                 fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
  534.                         p->p_type);
  535.                 exit(1);
  536.             }
  537.         }
  538.     }
  539.     fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, argname);
  540.     exit(1);
  541. }
  542.